<template>
  <van-notify v-model:show="show" type="success">
    <van-icon style="margin-right: 4px" />
    <span>打招呼成功!请耐心等待{{ name }}的回应...</span>
  </van-notify>
  <template v-if="user">
    <van-popup
      v-model:show="showPopup"
      position="top"
      :style="{ height: '26%' }"
      ><van-form @submit="onSubmitEdit">
        <van-field
          clearable
          v-if="editKey === 'userPassword'"
          v-model="oldPassword"
          label="旧密码"
          :placeholder="`请输入旧密码`"
        />
        <van-field
          v-if="
            editKey === 'username' ||
            editKey === 'email' ||
            editKey === 'userPassword' ||
            editKey === 'note'
          "
          clearable
          v-model="editValue"
          :label="`新${editName}`"
          :placeholder="`请输入${editName}`"
          :class="[
            editKey === 'username' || editKey === 'email' ? 'nameEmClass' : '',
          ]"
          @blur="edit(editKey, editValue)"
        />
        <van-field
          clearable
          v-if="editKey === 'userPassword'"
          v-model="againPassword"
          label="确认密码"
          :placeholder="`请输入确认密码`"
          @blur="editPasswordVer"
        />
        <van-radio-group
          v-if="editKey === 'gender'"
          class="genderClass"
          v-model="editValue"
          direction="horizontal"
        >
          <van-radio name="1">男 </van-radio>
          <van-radio class="genSecClass" name="0">女</van-radio>
        </van-radio-group>
        <van-field
          clearable
          v-if="editKey === 'avatarUrl'"
          :label="`修改${editName}`"
        >
          <template #input>
            <van-uploader
              :before-read="beforeRead"
              :after-read="afterRead"
              v-model="fileList"
              :max-count="1"
            />
          </template>
        </van-field>
        <div v-if="editKey !== 'logout'" style="margin: 16px">
          <van-button round block type="primary" native-type="submit">
            保存
          </van-button>
        </div>
      </van-form> </van-popup
    ><van-barrage
      v-model="messageList"
      duration="10000"
      style="--van-barrage-color: aqua"
    >
      <div class="center">
        <div style="width: 80px">
          <table>
            <van-tag
              plaino
              type="danger"
              v-for="tag in user.tags"
              style="margin-right: 8px; margin-top: 8px"
            >
              <tr>
                <td>{{ tag }}</td>
              </tr>
            </van-tag>
          </table>
        </div>
        <div>
          <van-image
            :alt="user.username"
            radius="20%"
            class="img"
            :src="user.avatarUrl"
            @click="showImagePreview([user.avatarUrl])"
          />
        </div>
        <div style="width: 80px">
          <van-button
            v-if="!isSameUser"
            style="margin-left: 30px; margin-top: 30px; font-size: 14px"
            size="large"
            color="linear-gradient(to right, #ff6034, #ee0a24)"
            @click="showCenter = true"
            >给ta留言</van-button
          >
        </div>
      </div>
    </van-barrage>
    <van-cell title="ID" icon="award-o" :value="user.planetCode" />
    <van-cell
      title="昵称"
      icon="user-o"
      :value="`${user.username}${
        !isSameUser && isFriend ? '(' + isFriend.note + ')' : ''
      }`"
    />
    <van-cell title="性别" icon="like-o">
      <img
        :src="user.gender === 1 ? '/img/boy.jpg' : '/img/girl.jpg'"
        width="25"
        height="25"
    /></van-cell>
    <van-cell title="手机号/账号" icon="phone-o" :value="user.phone" />
    <van-cell title="邮箱" icon="envelop-o" :value="user.email" />
    <van-cell
      title="注册时间"
      icon="passed"
      :value="moment(Number(user.createTime)).format('YYYY-MM-DD')"
    />
    <van-cell
      :title="`${isSameUser ? '我' : 'Ta'}的队伍`"
      icon="cluster-o"
      is-link
      @click="toUserTeam"
    />
  </template>
  <template v-if="visitorListSimple.length !== 0">
    <van-button plain type="success" @click="visitorFull" class="visitorClass">
      <div class="visitorFont">我的访客</div>
      <span v-for="visitorSimple of visitorListSimple">
        <img :src="visitorSimple" class="usersImgUrl" />
      </span>
      <span class="omit">
        <van-icon name="arrow" style="margin-top: 8px" />
      </span>
    </van-button>
  </template>
  <van-popup
    v-model:show="showLeft"
    position="left"
    :style="{ width: '80%', height: '100%' }"
  >
    <div style="font-size: 16px; margin-left: 40px">
      近七天有<span class="numClass">{{ visitorNum }}</span
      >名火友访问过你的主页
    </div>
    <user-card-list
      :user-list="userList"
      :show-tag="false"
      :loading="loading"
      isGetUser="1"
      isDetail="0"
      @showNotify="showNotifyDny"
    />
    <div class="vip">开通VIP可查看七天之前的访客记录</div>
  </van-popup>
  <van-button
    v-if="isSameUser"
    class="add-button"
    color="#7232dd"
    icon="records"
    @click="showCenter = true"
  />
  <van-button
    v-if="!isSameUser && !isFriend"
    block
    type="primary"
    @click="showNoteDialog = true"
    >添加好友</van-button
  >
  <van-button
    v-if="!isSameUser && isFriend"
    block
    type="primary"
    @click="toChat(user.id)"
    >发送信息</van-button
  >
  <van-dialog
    v-else
    v-model:show="showNoteDialog"
    :title="`添加好友:${user.username}`"
    show-cancel-button
    @confirm="friengMsg"
    @cancel="addFriendNote = ''"
  >
    <van-field
      clearable
      placeholder="我是......"
      style="text-align: center; width: 150px; margin-left: 75px"
      v-model="addFriendNote"
    />
  </van-dialog>
  <van-popup v-model:show="showCenter" round :style="{ padding: '64px' }">
    <van-cell-group>
      <div v-if="isSameUser" style="margin-left: 5%; font-size: 14px">
        给这次的体验评个评分
      </div>
      <div v-if="isSameUser" style="margin-left: 10%">
        <van-rate
          v-model="star"
          :size="25"
          color="#ffd21e"
          void-icon="star"
          void-color="#eee"
        />
      </div>
      <van-field
        clearable
        v-model="userSpeak"
        rows="1"
        autosize
        type="textarea"
        :maxlength="isSameUser ? 100 : 18"
        show-word-limit
        :placeholder="isSameUser ? '输入你的反馈......' : '输入你的留言......'"
      />
      <van-button type="primary" block @click="onSubmitSpeak">确认</van-button>
    </van-cell-group>
  </van-popup>
  <van-action-sheet
    v-model:show="showSheet"
    :actions="!isSameUser && isFriend ? actionsFri : actionsMy"
    description="设置"
    cancel-text="取消"
    close-on-click-action
    @select="onSelect"
  />
</template>

<script setup lang="ts">
import moment from "moment";
import myAxios from "../plugins/myAxios";
import UserCardList from "../components/UserCardList.vue";
import { UserType } from "../models/user";
import { FriendsType } from "../models/friends";
import { useRoute, useRouter } from "vue-router";
import { getCurrentUser } from "../services/user";
import { inject, onMounted, ref, watch } from "vue";
import { setCurrentUserState } from "../states/user";
import {
  showFailToast,
  showSuccessToast,
  showDialog,
  showConfirmDialog,
  showNotify,
  showImagePreview,
} from "vant";

const show = ref(false); //展示消息通知
const name = ref(""); //反馈打招呼对象的昵称
//展示打招呼的反馈信息，由子组件触发
const showNotifyDny = (showNot: boolean, username: string) => {
  show.value = showNot;
  name.value = username;
  setTimeout(() => {
    show.value = false;
  }, 2500);
};

const showCenter = ref(false); //展示用户反馈面板
let star = ref(0); //用户评分
let userSpeak = ref(""); //用户反馈的内容
const onSubmitSpeak = async () => {
  if (!isSameUser.value) {
    visitorMsgAdd();
  } else {
    if (star.value === 0) {
      showFailToast("小智遗憾告知:还没有星星呢");
      return;
    }
    if (userSpeak.value.trim() === "") {
      showFailToast("小智遗憾告知:多少说几句嘛");
      return;
    }
    showCenter.value = false;
    const res = await myAxios.post("/user/speak", {
      star: Number(star.value),
      speak: userSpeak.value,
    });
    if (res.code === 0) {
      star.value = 0;
      userSpeak.value = "";
      showSuccessToast("小智暖心提醒:感谢你的反馈");
    } else {
      showFailToast(`小智遗憾告知:${res.message}`);
    }
  }
};

const showSheet = ref(false); //展示动作面板以选择修改项
interface UserProps {
  showNavByLay: number;
}
const props = withDefaults(defineProps<UserProps>(), {
  showNavByLay: 0,
});
watch(
  () => props.showNavByLay,
  () => {
    if (isSameUser.value || isFriend.value) {
      showSheet.value = true;
    }
  }
);

const actionsMy = [
  { name: "修改昵称", key: 1 },
  { name: "修改性别", key: 2 },
  { name: "修改邮箱", key: 3 },
  { name: "修改密码", key: 4 },
  { name: "修改标签", key: 5 },
  { name: "修改头像", key: 6 },
  { name: "退出账号", key: 7 },
];

const actionsFri = [
  { name: "修改备注", key: 100 },
  { name: "删除好友", key: 200 },
];

const user = ref({} as UserType);
const showPopup = ref(false); //展示修改层
const editName = ref(""); //修改项的名字
const editKey = ref(""); //具体展示那个修改项
const editValue = ref(); //修改项的旧值
const onSelect = (item: { key: number }) => {
  showPopup.value = true;
  if (!isSameUser.value && isFriend.value) {
    if (item.key == 100) {
      editName.value = "备注";
      editKey.value = "note";
      editValue.value = isFriend.value.note;
    } else if (item.key == 200) {
      showPopup.value = false;
      showConfirmDialog({
        message: "确认删除好友吗",
      })
        .then(async () => {
          friendDelete(2);
        })
        .catch(() => {});
    }
  } else {
    if (item.key == 1) {
      editName.value = "昵称";
      editKey.value = "username";
      editValue.value = user.value.username;
    } else if (item.key == 2) {
      editName.value = "性别";
      editKey.value = "gender";
      editValue.value = user.value.gender;
    } else if (item.key == 3) {
      editName.value = "邮箱";
      editKey.value = "email";
      editValue.value = user.value.email;
    } else if (item.key == 4) {
      editName.value = "密码";
      editKey.value = "userPassword";
      editValue.value = "";
    } else if (item.key == 5) {
      toEditTags(user.value.id);
    } else if (item.key == 6) {
      editUrl();
    } else {
      showPopup.value = false;
      editKey.value = "logout";
      Logout();
    }
  }
};

const ver = ref(false); //表单校验是否通过
const special = /[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/; //匹配特殊字符的正则
let edit = (key: string, value: string) => {
  ver.value = false;
  if (value.trim() === "") {
    showNotify({
      type: "danger",
      message: `新${editName.value}不能为空`,
      duration: 1500,
    });
    return;
  }
  if (special.test(value) && editKey.value !== "email") {
    showNotify({
      type: "danger",
      message: `${editName.value}不能包含特殊字符`,
      duration: 1500,
    });
    return;
  }
  if (key == "userPassword") {
    if (value.length < 8 || value.length > 16) {
      showNotify({
        type: "danger",
        message: "密码长度必须在8-16位之间",
        duration: 1500,
      });
      return;
    }
    if (!value.match(/^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$/)) {
      showNotify({
        type: "danger",
        message: "密码必须只包含数字和字母",
        duration: 1500,
      });
      return;
    }
  } else if (key == "username") {
    if (value.length < 1 || value.length > 6) {
      showNotify({
        type: "danger",
        message: "昵称长度必须在1-6位之间",
        duration: 1500,
      });
      return;
    }
  } else if (key == "email") {
    const emailTest = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
    if (!emailTest.test(value)) {
      showNotify({ type: "danger", message: "邮箱格式错误", duration: 1500 });
      return;
    }
  } else if (key == "note") {
    if (value.length < 1 || value.length > 6) {
      showNotify({
        type: "danger",
        message: "备注长度必须在1-6位之间",
        duration: 1500,
      });
      return;
    }
  }
  ver.value = true;
};

const againPassword = ref(""); //确认密码
const editPasswordVer = () => {
  if (editValue.value != againPassword.value) {
    showFailToast("小智遗憾告知:两次密码不一致!");
    ver.value = false;
    return;
  }
};

const editUrl = () => {
  editName.value = "头像";
  editKey.value = "avatarUrl";
  showPopup.value = true;
};

let data = new FormData(); //上传至后端的图片对象
const beforeRead = () => {
  data.delete("data"); //每次上传图片前都清空上次上传的记录
  return true;
};

const urlSize = ref(true); //图片大小
const afterRead = async (file: {
  file: string | Blob;
  status: string;
  message: string;
}) => {
  urlSize.value = true;
  if (file.file.size > 3 * 1024 * 1024) {
    urlSize.value = false;
    file.status = "failed";
    file.message = "图片大小不能超过 3MB";
  } else data.append("data", file.file);
};

const reload = inject("reload"); //刷新页面的函数
const oldPassword = ref(""); //旧密码
const fileList = ref([]); //暂存图片的数组
//上传图片设置请求头
let config = {
  headers: { "Content-Type": "multipart/form-data" },
};
const onSubmitEdit = async () => {
  if (editKey.value === "avatarUrl" && urlSize.value) {
    fileList.value[0].status = "uploading";
    fileList.value[0].message = "上传中...";
    myAxios
      .post("/user/upload", data, config)
      .then((res) => {
        if (res.code === 0) {
          urlSize.value = true;
          setCurrentUserState(null);
          showSuccessToast("小智暖心提醒:上传成功");
          reload();
        }
      })
      .catch(() => {
        fileList.value[0].status = "failed";
        fileList.value[0].message = "上传失败";
        showFailToast("小智遗憾告知:请刷新重试");
      });
  } else if (editKey.value === "note") {
    if (isFriend.value.note == editValue.value) {
      showFailToast("小智遗憾告知:没有变化，无需修改");
      return;
    }
    if (!ver.value) {
      showFailToast("小智遗憾告知:备注不符合要求");
      return;
    }
    noteUpdate();
  } else {
    if (!ver.value) {
      showFailToast("小智遗憾告知:请检查所填数据");
      return;
    }
    if (user.value[editKey.value] == editValue.value) {
      showFailToast("小智遗憾告知:没有变化，无需修改");
      return;
    }
    if (editKey.value === "userPassword") {
      editValue.value += "-" + oldPassword.value;
    }
    const res = await myAxios.post("/user/update", {
      id: user.value.id,
      [editKey.value as string]: editValue.value,
    });
    editValue.value = "";
    if (res.code == 0) {
      setCurrentUserState(null); //将本地的用户数据清空以重新获取更新后的用户信息
      showSuccessToast(`小智暖心提醒:${editName.value}修改成功`);
      reload();
    } else {
      showFailToast(`小智遗憾告知:${res.message}`);
    }
  }
};

/**
 * 去修改标签
 */
const router = useRouter();
const toEditTags = (id: number) => {
  router.push({
    path: "/user/editTags",
    query: {
      id,
    },
  });
};

/**
 * 退出账号
 */
const Logout = async () => {
  showConfirmDialog({
    message: "确认退出账号吗",
  })
    .then(async () => {
      const res = await myAxios.get("/user/logout", {
        params: {
          userId: user.value.id,
        },
      });
      if (res.code == 0) {
        setCurrentUserState(null);
        router.push({
          path: "/user/login",
          replace: true,
        });
      } else {
        showFailToast("小智遗憾告知:未知错误");
      }
    })
    .catch(() => {});
};

/**
 * 与好友私聊
 */
const toChat = (friendId: number) => {
  router.push({
    path: "/chat",
    query: {
      scope: 1,
      friendId,
      friendInfo: JSON.stringify(isFriend.value),
      friendly: true,
    },
  });
};

/**
 * 增加一次条访客记录
 */
const currentUser = ref({} as UserType); //当前用户
const visitorAdd = async () => {
  myAxios.post("/visitor/add", {
    toId: user.value.id,
    fromId: currentUser.value.id,
    fromUrl: currentUser.value.avatarUrl ?? "",
    message: "",
    stealth: 0,
  });
};

/**
 * 增加一次条留言记录
 */
const visitorMsgAdd = async () => {
  showCenter.value = false;
  const res = await myAxios.post("/visitor/msg", {
    toId: user.value.id,
    fromId: currentUser.value.id,
    fromName: currentUser.value.username,
    fromUrl: currentUser.value.avatarUrl ?? "",
    message: userSpeak.value,
    stealth: 0,
  });
  if (res.code === 0) {
    userSpeak.value = "";
    showSuccessToast("小智暖心提醒:留言成功");
  } else {
    showFailToast(`小智遗憾告知:${res.message}`);
  }
};

/**
 * 查询最近5个访客的头像及留言
 */
const messageList = ref([]); //访客留言列表
const visitorListSimple = ref([]); //访客头像列表
const visitorSimple = async () => {
  const res = await myAxios.get("/visitor/simple", {
    params: {
      userId: user.value.id,
    },
  });
  if (res?.code == 0 && res.data) {
    res.data.forEach((r: string) => {
      let visitorSimple = JSON.parse(r);
      if (visitorSimple.message) {
        messageList.value.push({
          id: Math.random(),
          text: visitorSimple.fromName + ":" + visitorSimple.message,
        });
      }
      visitorListSimple.value.push(visitorSimple.fromUrl);
    });
  } else {
    showFailToast("小智遗憾告知:访客信息加载失败");
  }
};

/**
 * 查询近七天的访客列表
 */
const showLeft = ref(false); //是否展示左侧弹出层里的访客列表
const loading = ref(false); //是否处于加载状态
const userList = ref([]); //访客列表
const visitorNum = ref(0); //访客数量
const myFriendIdList = ref([]); //所有好友的id列表
const visitorFull = async () => {
  showLeft.value = true;
  userList.value = [];
  await myAxios
    .get("/user/myFriendId", {
      params: {
        userId: user.value.id,
      },
    })
    .then((res) => {
      if (res.code === 0 && res.data) {
        myFriendIdList.value = res.data;
      }
    });
  const res = await myAxios.get("/visitor/full", {
    params: {
      userId: user.value.id,
    },
  });
  if (res?.code == 0) {
    if (res.data.length !== 0) {
      res.data.forEach((user: UserType) => {
        if (user.tags) {
          user.tags = JSON.parse(user.tags);
        }
        if (myFriendIdList.value.find((id) => id === user.id)) {
          user.isMyFriend = true;
        }
        userList.value.push(user);
      });
    }
    visitorNum.value = userList.value.length;
  } else {
    showFailToast("小智遗憾告知:访客列表加载失败");
  }
};

/**
 * 发送好友请求
 */
const addFriendNote = ref(""); //自定义在好友处显示的备注
const showNoteDialog = ref(false); //是否展示添加好友的验证信息
const friengMsg = async () => {
  if (!addFriendNote.value) {
    addFriendNote.value = user.value.username;
  }
  const res = await myAxios.post("/friends/msg", {
    userId: user.value.id,
    userName: user.value.username,
    userUrl: user.value.avatarUrl,
    friendId: currentUser.value.id,
    friendName: currentUser.value.username,
    friendUrl: currentUser.value.avatarUrl,
    note: addFriendNote.value,
    status: 0,
  });
  addFriendNote.value = "";
  if (res.code === 0) {
    reload();
    showSuccessToast("小智暖心提醒:发送成功");
  } else {
    showFailToast(`小智遗憾告知:${res.message}`);
  }
};

/**
 * 修改好友备注
 */
const noteUpdate = async () => {
  const res = await myAxios.post("/friends/update", {
    id: isFriend.value.id,
    userId: isFriend.value.userId,
    friendId: isFriend.value.friendId,
    note: editValue.value,
  });
  if (res.code === 0) {
    showSuccessToast("小智暖心提醒:备注修改成功");
    reload();
  } else {
    showFailToast(`小智遗憾告知:${res.message}`);
  }
};

/**
 * 删除好友
 */
const friendDelete = async (num: number) => {
  const res = await myAxios.post("/friends/delete", {
    id: isFriend.value.id,
    userId: isFriend.value.userId,
    friendId: isFriend.value.friendId,
    oneOrTwo: num,
  });
  if (res.code === 0) {
    showSuccessToast("小智暖心提醒:删除成功");
    reload();
  } else {
    showFailToast(`小智遗憾告知:${res.message}`);
  }
};

/**
 * 当前访问的主页是否为自己好友
 */
const isFriend = ref({} as FriendsType); //根据是否能查到好友数据判断是否有好友关系
const getIsFriend = async (userId: number, friendId: number) => {
  loading.value = true;
  const res = await myAxios.get("/friends/isFriend", {
    params: {
      userId,
      friendId,
    },
  });
  if (res.code === 0) {
    isFriend.value = res.data;
  }
  loading.value = false;
};

/**
 * 查看我/ta的队伍
 */
const route = useRoute();
const isSameUser = ref(true); //当前访问的主页是否为自己的
const toUserTeam = () => {
  router.push({
    path: "/user/team",
    query: {
      userId: user.value.id,
      currentUserId: currentUser.value.id ?? user.value.id,
    },
  });
};

onMounted(async () => {
  let otherUser = route.query.userObj;
  const friendInfo = route.query.friendInfo;
  if (otherUser || friendInfo) {
    isSameUser.value = false;
    currentUser.value = await getCurrentUser("1");
    if (friendInfo) {
      //从聊天页、好友列表和好友申请信息访问别人主页
      isFriend.value = JSON.parse(friendInfo);
      const res = await myAxios.get("/user/other", {
        params: {
          otherUserId: Number(isFriend.value.friendId ?? isFriend.value.fromId),
        },
      });
      if (res.code === 0 && res.data) {
        user.value = res.data;
      }
    } else {
      //从首页、队伍详情页等访问别人主页
      otherUser = JSON.parse(otherUser);
      user.value = otherUser;
      getIsFriend(currentUser.value.id, user.value.id);
    }
    visitorAdd();
  } else {
    //查看的是自己主页
    user.value = await getCurrentUser("1");
    visitorSimple();
  }
  if (user.value.tags) {
    if (typeof user.value.tags == "string") {
      user.value.tags = JSON.parse(user.value.tags);
    }
  } else if (isSameUser.value) {
    showDialog({
      message: "先去选一下自己的标签吧......",
    }).then(() => {
      toEditTags(user.value.id);
    });
  }
});
</script>

<style scoped>
@import "../assets/css/public.css";
@import "../assets/css/UserPage.css";
</style>
